﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Collections;
using System.Text.RegularExpressions;
//using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace Serial
{
    public partial class Form1 : Form
    {
        // 接受十六进制的时候  结尾的空格没有加！

        private bool isOpen = false;
        private bool isPause = false;
        // 接受缓存
        private List<byte> receiveBuff = new List<byte>();
        // 发送缓存
        private List<byte> sendBuff = new List<byte>();
        private int receiveCnt = 0;
        private int sendCnt = 0;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            serialLoad();
        }

        private void serialLoad()
        {
            com_cbb.Items.Clear();
            string[] portNames = SerialPort.GetPortNames();
            foreach (string portName in portNames)
            {
                com_cbb.Items.Add(portName);
            }
            this.com_cbb.SelectedIndex = 0;
            this.baud_cbb.SelectedIndex = 0;
            this.check_cbb.SelectedIndex = 0;
            this.databit_cbb.SelectedIndex = 3;
            this.stopbit_cbb.SelectedIndex = 0;
        }

        private byte[] convertStrtoByteArray(String hexStr)
        {
            if (hexStr.Length >= 2)
            {
                byte[] byteArray = new byte[hexStr.Length / 2];
                for (int i = 0; i < hexStr.Length; i += 2)
                {
                    byteArray[i / 2] = Convert.ToByte(hexStr.Substring(i, 2), 16);
                }
                return byteArray;
            }
            else
            {
                return null;
            }



        }
        private void sendData()
        {
                serialPort.Write(sendBuff.ToArray(), 0, sendBuff.Count);
                sendCnt += sendBuff.Count;
                sendCnt_tssl.Text = sendCnt.ToString();
        }
        private void open_btn_Click(object sender, EventArgs e)
        {
            try
            {   
                if(serialPort.IsOpen==false)
                {
                    serialPort.PortName = com_cbb.Text;
                    serialPort.BaudRate = Convert.ToInt32(baud_cbb.Text);
                    serialPort.DataBits = Convert.ToInt32(databit_cbb.Text);
                    switch(check_cbb.SelectedIndex)
                    {
                        case 0:
                            serialPort.Parity = Parity.None;
                            break;
                        case 1:
                            serialPort.Parity = Parity.Odd;
                            break;
                        case 2:
                            serialPort.Parity = Parity.Even;
                            break;
                        default:
                            serialPort.Parity = Parity.None;
                            break;
                    }
                    switch(stopbit_cbb.SelectedIndex)
                    {
                        case 0:
                            serialPort.StopBits = StopBits.One;
                            break;
                        case 1:
                            serialPort.StopBits = StopBits.OnePointFive;
                            break;
                        case 2:
                            serialPort.StopBits = StopBits.Two;
                            break;
                        default:
                            serialPort.StopBits = StopBits.One;
                            break;
                    }

                    this.serialPort.Open();

                    isOpen = true;
                    open_btn.Text = "关闭串口";
                }
                else
                {
                    this.serialPort.Close();
                    isOpen = false;
                    open_btn.Text = "打开串口";
                }
                
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString()+serialPort.PortName.ToString());
                //throw;
            }
        }

        private void send_btn_Click(object sender, EventArgs e)
        {
            if(isOpen)
            {
                sendData();
            }
            else
            {
                MessageBox.Show("请先打开串口！");
            }
        }

        private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (isPause) return;

            byte[] dataTemp = new byte[serialPort.BytesToRead];
            serialPort.Read(dataTemp, 0, dataTemp.Length);
            receiveBuff.AddRange(dataTemp);
            receiveCnt += dataTemp.Length;
            string dataReceived;

            receiveCnt_tssl.Text = receiveCnt.ToString();

            if (!receiveHex_chb.Checked)
            {
                dataReceived = Encoding.GetEncoding("gb2312").GetString(dataTemp).Replace("\0", "\\0");
            }
            else
            {
                // 勾选了Hex显示
                dataReceived = BitConverter.ToString(dataTemp).Replace("-"," ");
            }         

            if (receive_rtb.InvokeRequired)
            {
                MethodInvoker updateTextDelegate = () => receive_rtb.AppendText(dataReceived);
                receive_rtb.BeginInvoke(updateTextDelegate);
            }
            else
            {
                receive_rtb.AppendText(dataReceived);
            }

        }

        private void pause_btn_Click(object sender, EventArgs e)
        {
            if (isPause)
            {
                isPause = false;
                pause_btn.Text = "暂停";
            }
            else
            {
                isPause = true;
                pause_btn.Text = "取消暂停";
            }
        }

        private void receiveHex_chb_CheckedChanged(object sender, EventArgs e)
        {
            if (receiveHex_chb.Text == "") return;
            if(receiveHex_chb.Checked)
            {
                receive_rtb.Text = BitConverter.ToString(receiveBuff.ToArray()).Replace("-", " "); 
            }
            else
            {
                receive_rtb.Text = Encoding.GetEncoding("gb2312").GetString(receiveBuff.ToArray()).Replace("\0", "\\0");
            }
        }

        private void receiveClear_btn_Click(object sender, EventArgs e)
        {
            receiveBuff.Clear();
            receive_rtb.Text = "";
            receiveCnt_tssl.Text = "0";
            receiveCnt = 0;
        }

        private void autoClear_chb_CheckedChanged(object sender, EventArgs e)
        {
            if(autoClear_chb.Checked)
            {
                receiveAutoClearTimer.Start();
            }
            else
            {
                receiveAutoClearTimer.Stop();

            }
        }

        private void receiveAutoClearTimer_Tick(object sender, EventArgs e)
        {
            Console.WriteLine(receiveCnt.ToString());
            if(receiveCnt >= 4096)
            {
                receiveBuff.Clear();
                receive_rtb.Text = "";
                receiveCnt_tssl.Text = "0";
                receiveCnt = 0;
            }
        }


        private void sendHex_chb_CheckedChanged(object sender, EventArgs e)
        {
            if (send_rtb.Text == "") return;
            if (sendHex_chb.Checked)
            {
                send_rtb.Text = BitConverter.ToString(sendBuff.ToArray()).Replace("-", " ");
            }
            else
            {
                send_rtb.Text = Encoding.GetEncoding("gb2312").GetString(sendBuff.ToArray()).Replace("\0", "\\0");
            }
        }

        private void sendClear_btn_Click(object sender, EventArgs e)
        {
            sendBuff.Clear();
            sendCnt = 0;
            send_rtb.Text = "";
            sendCnt_tssl.Text = "0";
        }

        private void send_rtb_TextChanged(object sender, EventArgs e)
        {
            if (sendHex_chb.Checked)
            {
                // 这里检查十六进制数据不对   带空格的十六进制怎么转换
                if (Regex.IsMatch(send_rtb.Text.Trim(), @"^[0-9A-Fa-f]+$"))
                {
                    sendBuff.Clear();
                    if(convertStrtoByteArray(send_rtb.Text.Trim())!=null)
                    {
                        sendBuff.AddRange(convertStrtoByteArray(send_rtb.Text.Trim())); // #bug 转换16进制错误
                    }    
                }
                else
                {
                    //MessageBox.Show("请输入正确的十六进制数据！");
                    //send_rtb.Select();
                }
            }
            else
            {
                sendBuff.Clear();
                sendBuff.AddRange(Encoding.GetEncoding("gb2312").GetBytes(send_rtb.Text));
            }
        }
    }
}
